"""DHCP API路由."""

from typing import List, Optional

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession

from netsphere.core.database import get_db
from netsphere.services.dhcp import DHCPManager, LeaseManager, DHCPPoolManager
from netsphere.schemas.dhcp import (
    DHCPScopeCreate,
    DHCPScopeUpdate,
    DHCPScopeResponse,
    DHCPReservationCreate,
    DHCPReservationUpdate,
    DHCPReservationResponse,
    DHCPAllocationRequest,
    DHCPAllocationResponse,
    DHCPStatistics,
)

router = APIRouter(prefix="/dhcp", tags=["dhcp"])


@router.post("/scopes", response_model=DHCPScopeResponse)
async def create_dhcp_scope(
    scope: DHCPScopeCreate,
    db: AsyncSession = Depends(get_db),
):
    """创建DHCP作用域."""
    manager = DHCPPoolManager(db)
    try:
        return await manager.create_scope(**scope.dict())
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/scopes", response_model=List[DHCPScopeResponse])
async def list_dhcp_scopes(
    is_active: Optional[bool] = Query(None, description="是否激活"),
    db: AsyncSession = Depends(get_db),
):
    """列出DHCP作用域."""
    manager = DHCPPoolManager(db)
    scopes = await manager.list_scopes(is_active=is_active)
    
    # 添加统计信息
    responses = []
    for scope in scopes:
        stats = await manager.get_scope_stats(scope.id)
        utilization = await manager.get_scope_utilization(scope.id)
        
        response = DHCPScopeResponse(
            **scope.__dict__,
            total_ips=stats["total_ips"],
            used_ips=stats["used_ips"],
            available_ips=stats["available_ips"],
            utilization=utilization["utilization"],
        )
        responses.append(response)
    
    return responses


@router.get("/scopes/{scope_id}", response_model=DHCPScopeResponse)
async def get_dhcp_scope(
    scope_id: int,
    db: AsyncSession = Depends(get_db),
):
    """获取DHCP作用域详情."""
    manager = DHCPPoolManager(db)
    scope = await manager.get_scope(scope_id)
    if not scope:
        raise HTTPException(status_code=404, detail="Scope not found")
    
    stats = await manager.get_scope_stats(scope_id)
    utilization = await manager.get_scope_utilization(scope_id)
    
    return DHCPScopeResponse(
        **scope.__dict__,
        total_ips=stats["total_ips"],
        used_ips=stats["used_ips"],
        available_ips=stats["available_ips"],
        utilization=utilization["utilization"],
    )


@router.put("/scopes/{scope_id}", response_model=DHCPScopeResponse)
async def update_dhcp_scope(
    scope_id: int,
    scope_update: DHCPScopeUpdate,
    db: AsyncSession = Depends(get_db),
):
    """更新DHCP作用域."""
    # TODO: 实现作用域更新功能
    raise HTTPException(status_code=501, detail="Not implemented")


@router.delete("/scopes/{scope_id}")
async def delete_dhcp_scope(
    scope_id: int,
    db: AsyncSession = Depends(get_db),
):
    """删除DHCP作用域."""
    # TODO: 实现作用域删除功能
    raise HTTPException(status_code=501, detail="Not implemented")


@router.post("/scopes/{scope_id}/reservations", response_model=DHCPReservationResponse)
async def create_dhcp_reservation(
    scope_id: int,
    reservation: DHCPReservationCreate,
    db: AsyncSession = Depends(get_db),
):
    """创建DHCP保留地址."""
    manager = DHCPPoolManager(db)
    try:
        return await manager.create_reservation(
            scope_id=scope_id,
            **reservation.dict()
        )
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/scopes/{scope_id}/reservations", response_model=List[DHCPReservationResponse])
async def list_dhcp_reservations(
    scope_id: int,
    is_active: Optional[bool] = Query(None, description="是否激活"),
    db: AsyncSession = Depends(get_db),
):
    """列出DHCP保留地址."""
    manager = DHCPPoolManager(db)
    return await manager.list_reservations(scope_id=scope_id, is_active=is_active)


@router.get("/scopes/{scope_id}/reservations/{reservation_id}", response_model=DHCPReservationResponse)
async def get_dhcp_reservation(
    scope_id: int,
    reservation_id: int,
    db: AsyncSession = Depends(get_db),
):
    """获取DHCP保留地址详情."""
    # TODO: 实现保留地址详情查询
    raise HTTPException(status_code=501, detail="Not implemented")


@router.put("/scopes/{scope_id}/reservations/{reservation_id}", response_model=DHCPReservationResponse)
async def update_dhcp_reservation(
    scope_id: int,
    reservation_id: int,
    reservation_update: DHCPReservationUpdate,
    db: AsyncSession = Depends(get_db),
):
    """更新DHCP保留地址."""
    # TODO: 实现保留地址更新功能
    raise HTTPException(status_code=501, detail="Not implemented")


@router.delete("/scopes/{scope_id}/reservations/{reservation_id}")
async def delete_dhcp_reservation(
    scope_id: int,
    reservation_id: int,
    db: AsyncSession = Depends(get_db),
):
    """删除DHCP保留地址."""
    # TODO: 实现保留地址删除功能
    raise HTTPException(status_code=501, detail="Not implemented")


@router.post("/allocate", response_model=DHCPAllocationResponse)
async def allocate_dhcp_ip(
    allocation: DHCPAllocationRequest,
    db: AsyncSession = Depends(get_db),
):
    """分配DHCP地址."""
    pool_manager = DHCPPoolManager(db)
    lease_manager = LeaseManager(db)
    
    # 检查是否有保留地址
    reservation = await pool_manager.get_reservation_by_mac(
        allocation.scope_id,
        allocation.mac_address
    )
    
    if reservation:
        # 使用保留地址
        ip_address = reservation.ip_address
    else:
        # 分配动态地址
        ip_address = await pool_manager.get_available_ip(
            allocation.scope_id,
            allocation.requested_ip
        )
        
        if not ip_address:
            raise HTTPException(status_code=409, detail="No available IP addresses")
    
    # 创建租约
    import datetime
    lease_start = datetime.datetime.utcnow()
    lease_end = lease_start + datetime.timedelta(seconds=86400)  # 默认24小时
    
    lease = await lease_manager.create_lease(
        scope_id=allocation.scope_id,
        ip_address=ip_address,
        mac_address=allocation.mac_address,
        hostname=allocation.hostname,
        lease_start=lease_start,
        lease_end=lease_end,
    )
    
    # 获取作用域配置
    scope = await pool_manager.get_scope(allocation.scope_id)
    
    return DHCPAllocationResponse(
        ip_address=lease.ip_address,
        subnet_mask=scope.subnet_mask,
        gateway=scope.gateway,
        dns_servers=scope.dns_servers,
        domain_name=scope.domain_name,
        lease_time=scope.lease_time,
        lease_start=lease.lease_start,
        lease_end=lease.lease_end,
    )


@router.post("/leases/{lease_id}/renew")
async def renew_dhcp_lease(
    lease_id: int,
    db: AsyncSession = Depends(get_db),
):
    """续租DHCP地址."""
    lease_manager = LeaseManager(db)
    
    import datetime
    new_lease_end = datetime.datetime.utcnow() + datetime.timedelta(seconds=86400)
    
    lease = await lease_manager.renew_lease(lease_id, new_lease_end)
    if not lease:
        raise HTTPException(status_code=404, detail="Lease not found")
    
    return {"message": "Lease renewed successfully", "lease_end": lease.lease_end}


@router.post("/leases/{lease_id}/release")
async def release_dhcp_lease(
    lease_id: int,
    db: AsyncSession = Depends(get_db),
):
    """释放DHCP地址."""
    lease_manager = LeaseManager(db)
    
    success = await lease_manager.release_lease(lease_id)
    if not success:
        raise HTTPException(status_code=404, detail="Lease not found")
    
    return {"message": "Lease released successfully"}


@router.get("/leases", response_model=List[Dict])
async def list_dhcp_leases(
    scope_id: Optional[int] = Query(None, description="作用域ID"),
    state: Optional[str] = Query(None, description="租约状态"),
    db: AsyncSession = Depends(get_db),
):
    """列出DHCP租约."""
    lease_manager = LeaseManager(db)
    leases = await lease_manager.list_leases(
        scope_id=scope_id,
        state=state,
    )
    
    return [
        {
            "id": lease.id,
            "ip_address": lease.ip_address,
            "mac_address": lease.mac_address,
            "hostname": lease.hostname,
            "state": lease.state,
            "lease_start": lease.lease_start,
            "lease_end": lease.lease_end,
        }
        for lease in leases
    ]


@router.get("/statistics", response_model=DHCPStatistics)
async def get_dhcp_statistics(
    db: AsyncSession = Depends(get_db),
):
    """获取DHCP统计信息."""
    pool_manager = DHCPPoolManager(db)
    lease_manager = LeaseManager(db)
    
    # 统计作用域
    scopes = await pool_manager.list_scopes()
    active_scopes = [s for s in scopes if s.is_active]
    
    # 统计租约
    all_leases = await lease_manager.list_leases()
    active_leases = [l for l in all_leases if l.state == "active"]
    expired_leases = [l for l in all_leases if l.state == "expired"]
    
    # 统计保留地址
    reservations = await pool_manager.list_reservations()
    
    # 计算整体使用率
    total_ips = 0
    used_ips = 0
    for scope in scopes:
        stats = await pool_manager.get_scope_stats(scope.id)
        total_ips += stats["total_ips"]
        used_ips += stats["used_ips"] + stats["reserved_ips"]
    
    utilization = (used_ips / total_ips * 100) if total_ips > 0 else 0.0
    
    return DHCPStatistics(
        total_scopes=len(scopes),
        active_scopes=len(active_scopes),
        total_leases=len(all_leases),
        active_leases=len(active_leases),
        expired_leases=len(expired_leases),
        reserved_ips=len(reservations),
        utilization=utilization,
    )


@router.post("/cleanup-expired")
async def cleanup_expired_leases(
    db: AsyncSession = Depends(get_db),
):
    """清理过期租约."""
    lease_manager = LeaseManager(db)
    
    count = await lease_manager.cleanup_expired_leases()
    
    return {"message": f"Cleaned up {count} expired leases"}